package org.abettor.angleworm.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.abettor.angleworm.auth.AccountType;
import org.abettor.angleworm.db.HibernateSessionFactory;
import org.abettor.angleworm.db.UsedMood;
import org.abettor.util.Environment;
import org.eclipse.swt.graphics.Rectangle;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 * 应用程序用户配置信息
 * @author shawn
 *
 */
public abstract class Configuration
{
	private static Properties propGlobal = new Properties();
	private static String confGlobal = Environment.getFilePath("conf/global.properties");
	private static Properties properties = new Properties();
	private static String conf = Environment.getUserDataDirectory() + "/config.properties";
	static
	{
		InputStream isGlobal = null;
		InputStream is = null;
		try
		{
			File file = new File(confGlobal);
			isGlobal = new FileInputStream(file);
			propGlobal.load(isGlobal);

			file = new File(conf);
			if(! file.getParentFile().exists())
			{
				file.getParentFile().mkdirs();
			}
			if(! file.exists())
			{
				file.createNewFile();
			}
			is = new FileInputStream(file);
			properties.load(is);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			if(isGlobal != null)
			{
				try
				{
					isGlobal.close();
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}

			if(is != null)
			{
				try
				{
					is.close();
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 获取全局配置信息
	 * @param key
	 */
	public static String getGlobalProperty(String key)
	{
		return propGlobal.getProperty(key, null);
	}

	/**
	 * 将配置信息持久化到用户配置文件
	 */
	public static void save()
	{
		File file = new File(conf);
		OutputStream os = null;
		try
		{
			os = new FileOutputStream(file);
			properties.store(os, null);
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			if(os != null)
			{
				try
				{
					os.close();
				}
				catch(IOException e)
				{
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 获取JMFHOME目录
	 */
	public static String getJmfHome()
	{
		String jmfHome = properties.getProperty("JMFHOME");
		if(jmfHome == null)
		{
			jmfHome = System.getProperty("JMFHOME");
			if(jmfHome == null)
			{
				jmfHome = System.getenv("JMFHOME");
			}
		}

		return jmfHome;
	}

	/**
	 * 设置JMFHOME目录
	 * @param jmfHome
	 */
	public static void setJmfHome(String jmfHome)
	{
		properties.setProperty("JMFHOME", jmfHome);
	}

	/**
	 * 获取本机绑定IP地址
	 */
	public static String getBindAddress()
	{
		String val = properties.getProperty("BIND_ADDRESS");
		if(val == null)
		{
			try
			{
				InetAddress localAddr = InetAddress.getLocalHost();
				return localAddr.getHostAddress();
			}
			catch (UnknownHostException e)
			{
				e.printStackTrace();
				return null;
			}
		}

		return val;
	}

	/**
	 * 设定本机绑定IP地址
	 * @param bindAddress
	 */
	public static void setBindAddress(String bindAddress)
	{
		properties.setProperty("BIND_ADDRESS", bindAddress);
	}

	/**
	 * 获取麦克风设备名称
	 */
	public static String getAudioCaptureDeviceName()
	{
		String val = properties.getProperty("AUDIO_DEVICE");
		if(val == null)
		{
			//TODO	尝试获取默认麦克风设备名称
		}

		return val;
	}

	/**
	 * 设置麦克风设备名称
	 * @param deviceName
	 */
	public static void setAudioCaptureDeviceName(String deviceName)
	{
		properties.setProperty("AUDIO_DEVICE", deviceName);
	}

	/**
	 * 获取摄像头设备名称
	 */
	public static String getVideoCaptureDeviceName()
	{
		String val = properties.getProperty("VIDEO_DEVICE");
		if(val == null)
		{
			//TODO	尝试获取默认摄像头设备名称
		}

		return val;
	}

	/**
	 * 设置摄像头设备名称
	 * @param deviceName
	 */
	public static void setVideoCaptureDeviceName(String deviceName)
	{
		properties.setProperty("VIDEO_DEVICE", deviceName);
	}

	/**
	 * 获取默认帐号类型
	 */
	public static AccountType getDefaultAccountType()
	{
		String type = properties.getProperty("ACCOUNT_TYPE");
		if(type == null || type.isEmpty())
		{
			return null;
		}

		AccountType accType = AccountType.valueOf(type);
		return accType;
	}

	/**
	 * 设置默认帐号类型
	 */
	public static void setDefaultAccountType(AccountType accountType)
	{
		if(accountType == null)
		{
			properties.setProperty("ACCOUNT_TYPE", "");
			return;
		}

		properties.setProperty("ACCOUNT_TYPE", accountType.name());
	}

	/**
	 * 检查是否已经同意了声明条款
	 */
	public static boolean isAgreementConfirmed()
	{
		String agreement = properties.getProperty("AGREEMENT_CONFIRMED");
		if(agreement == null || agreement.isEmpty())
		{
			return false;
		}

		return Boolean.parseBoolean(agreement);
	}

	/**
	 * 将声明条款置为同意
	 */
	public static void confirmAgreement()
	{
		properties.setProperty("AGREEMENT_CONFIRMED", String.valueOf(true));
	}

	/**
	 * 获取用户默认语言
	 */
	public static String getDefaultLanguage()
	{
		return properties.getProperty("DEFAULT_LANGUAGE");
	}

	/**
	 * 设置用户默认语言
	 * @param language
	 */
	public static void setDefaultLanguage(String language)
	{
		properties.setProperty("DEFAULT_LANGUAGE", language);
	}

	/**
	 * 获取用户保存的主窗口位置和大小信息
	 */
	public static Rectangle getMainDialogBounds()
	{
		String data = properties.getProperty("LAST_BOUNDS");
		if(data == null)
		{
			return null;
		}

		String[] nums = data.split(",");
		if(nums.length != 4)
		{
			return null;
		}

		try
		{
			int x = Integer.parseInt(nums[0]);
			int y = Integer.parseInt(nums[1]);
			int width = Integer.parseInt(nums[2]);
			int height = Integer.parseInt(nums[3]);
			return new Rectangle(x, y, width, height);
		}
		catch(Exception e)
		{
			return null;
		}
	}

	/**
	 * 设定主窗口位置和大小信息以备保存
	 * @param rect
	 */
	public static void setMainDialogBounds(Rectangle rect)
	{
		setMainDialogBounds(rect.x, rect.y, rect.width, rect.height);
	}

	/**
	 * 设定主窗口位置和大小信息以备保存
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 */
	public static void setMainDialogBounds(int x, int y, int width, int height)
	{
		String lastBounds = x + "," + y + "," + width + "," + height;
		properties.setProperty("LAST_BOUNDS", lastBounds);
	}

	/**
	 * 获取默认登录方式
	 */
	public static String getDefaultStatus()
	{
		return properties.getProperty("DEFAULT_STATUS");
	}

	/**
	 * 设定默认登录方式
	 * @param status
	 */
	public static void setDefaultStatus(String status)
	{
		properties.setProperty("DEFAULT_STATUS", status);
	}

	/**
	 * 获取曾经使用的心情短语
	 */
	@SuppressWarnings("unchecked")
	public static String[] getUsedMoods(String account)
	{
		try
		{
			Session ssn = HibernateSessionFactory.getSession();
			Criteria crtr = ssn.createCriteria(UsedMood.class);
			crtr.add(Restrictions.eq("account", account));
			crtr.addOrder(Order.desc("lastUsed"));
			List<UsedMood> list = crtr.list();
			if(list == null)
			{
				return new String[]{};
			}
	
			String[] moodArray = new String[list.size()];
			for(int i = 0; i < moodArray.length; i ++)
			{
				moodArray[i] = list.get(i).getMood();
			}
			return moodArray;
		}
		catch(HibernateException e)
		{
			e.printStackTrace();
			return new String[]{};
		}
		finally
		{
			HibernateSessionFactory.releaseSession();
		}
	}

	/**
	 * 获取当前正在使用的心情短语
	 */
	@SuppressWarnings("unchecked")
	public static String getCurrentMood(String account)
	{
		try
		{
			Session ssn = HibernateSessionFactory.getSession();
			Criteria crtr = ssn.createCriteria(UsedMood.class);
			crtr.add(Restrictions.eq("account", account));
			crtr.addOrder(Order.desc("lastUsed"));
			crtr.setMaxResults(1);
			List<UsedMood> list = crtr.list();
			if(list == null || list.isEmpty())
			{
				return null;
			}
	
			return list.get(0).getMood();
		}
		catch(HibernateException e)
		{
			e.printStackTrace();
			return null;
		}
		finally
		{
			HibernateSessionFactory.releaseSession();
		}
	}

	/**
	 * 设定当前心情短语，并将其加入到曾经使用的心情短语列表
	 * @param mood
	 */
	@SuppressWarnings("unchecked")
	public static void setCurrentMood(String account, String mood)
	{
		if(mood == null || mood.isEmpty())
		{
			return;
		}

		Transaction tx = null;
		try
		{
			Session ssn = HibernateSessionFactory.getSession();
			tx = ssn.beginTransaction();
			Criteria crtr = ssn.createCriteria(UsedMood.class);
			crtr.add(Restrictions.eq("account", account));
			crtr.add(Restrictions.eq("mood", mood));
			crtr.setMaxResults(1);
			List<UsedMood> list = crtr.list();
			UsedMood usedMood = null;
			if(list == null || list.isEmpty())
			{
				usedMood = new UsedMood();
				usedMood.setAccount(account);
				usedMood.setLastUsed(new Date());
				usedMood.setMood(mood);
			}
			else
			{
				usedMood = list.get(0);
			}

			ssn.saveOrUpdate(usedMood);
			tx.commit();
		}
		catch(HibernateException e)
		{
			e.printStackTrace();
			if(tx != null)
			{
				tx.rollback();
			}
		}
		finally
		{
			HibernateSessionFactory.releaseSession();
		}
	}
}
